/*
 * 
 * LegendShop 多用户商城系统
 * 
 *  版权所有,并保留所有权利。
 * 
 */
package com.legendshop.permission.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.legendshop.dao.support.PageSupport;
import com.legendshop.framework.commond.State;
import com.legendshop.framework.commond.StateImpl;
import com.legendshop.framework.controller.AdminController;
import com.legendshop.framework.controller.BaseController;
import com.legendshop.oa.constants.PathResolver;
import com.legendshop.oa.exception.BusinessException;
import com.legendshop.oa.exception.ErrorCodes;
import com.legendshop.oa.model.Function;
import com.legendshop.oa.model.Menu;
import com.legendshop.oa.model.Permission;
import com.legendshop.oa.model.PerssionId;
import com.legendshop.oa.model.Role;
import com.legendshop.oa.security.UserManager;
import com.legendshop.oa.util.PageSupportHelper;
import com.legendshop.permission.form.FunctionForm;
import com.legendshop.permission.form.MenuTree;
import com.legendshop.permission.form.PermissionForm;
import com.legendshop.permission.form.RoleForm;
import com.legendshop.permission.page.SecurityBackPage;
import com.legendshop.permission.page.SecurityFowardPage;
import com.legendshop.permission.page.SecurityTilesPage;
import com.legendshop.permission.service.FunctionService;
import com.legendshop.permission.service.MenuService;
import com.legendshop.permission.service.RightDelegate;
import com.legendshop.util.AppUtils;
import com.legendshop.util.JSONUtil;

/**
 * FunctionAdminController.
 */
@Controller
@RequestMapping("/admin/member/right")
public class FunctionAdminController extends BaseController implements AdminController<Function, Long> {
	
	/** The log. */
	private final static Logger log = LoggerFactory.getLogger(FunctionAdminController.class);

	/** The basket service. */
	@Autowired(required = false)
	private RightDelegate rightDelegate;
	
	@Autowired
	private MenuService menuService;
	
	@Autowired
	private FunctionService functionService;

	/**
	 * Delete function by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param curPageNO
	 *            the cur page no
	 * @param roleId
	 *            the role id
	 * @param functionForm
	 *            the function form
	 * @return the string
	 */
	@RequestMapping("/deleteFunctionById")
	public String deleteFunctionById(HttpServletRequest request, HttpServletResponse response, String curPageNO, String roleId,
			FunctionForm functionForm) {
		String id = request.getParameter("id");
		log.info("Struts Action deleteFunctionById with id  " + id);
		State state = new StateImpl();

		boolean result = rightDelegate.deleteFunctionById(Long.parseLong(id), state);
		log.debug("deleteFunctionById result  = " + result);

		return PathResolver.getPath(request, response, SecurityFowardPage.FUNCTION_LIST_QUERY);
	}

	/**
	 * Find function by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param id
	 *            the id
	 * @return the string
	 */
	@RequestMapping("/findFunctionById")
	public String findFunctionById(HttpServletRequest request, HttpServletResponse response, Long id) {
		log.info("Struts Action findFunctionById with id  " + id);
		State state = new StateImpl();
		Function function = rightDelegate.findFunctionById(id, state);
		request.setAttribute("function", function);

		return PathResolver.getPath(request, response, SecurityBackPage.UPDATE_FUNCTION);
	}

	/**
	 * Find function by role.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param roleId
	 *            the role id
	 * @return the string
	 */
	@RequestMapping("/findFunctionByRole")
	public String findFunctionByRole(HttpServletRequest request, HttpServletResponse response, Long roleId) {
		log.info("Struts FunctionAction findFunctionByRole with roleId  " + roleId);
		State state = new StateImpl();
		Role role = rightDelegate.findRoleById(roleId, state);
		List list = rightDelegate.findFunctionByRoleId(roleId, state);
		request.setAttribute("list", list);
		request.setAttribute("role", role);

		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_FUNCTION_BY_ROLE.getNativeValue() + "/" + roleId,
				SecurityFowardPage.FIND_FUNCTION_BY_ROLE);
	}


	/**
	 * Save function.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param functionForm
	 *            the function form
	 * @return the string
	 */
	@RequestMapping("/saveFunction")
	public String saveFunction(HttpServletRequest request, HttpServletResponse response, FunctionForm functionForm) {
		State state = new StateImpl();
		Long id = rightDelegate.saveFunction(functionForm.getFunction(), state);
		log.info("success saveFunction,id = " + id);
		return PathResolver.getPath(request, response, SecurityFowardPage.FUNCTION_LIST_QUERY);
	}

	/**
	 * Save functions to role list.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param roleId
	 *            the role id
	 * @param permissionForm
	 *            the permission form
	 * @return the string
	 */
	@RequestMapping("/saveFunctionsToRoleList")
	public String saveFunctionsToRoleList(HttpServletRequest request, HttpServletResponse response, Long roleId,
			PermissionForm permissionForm) {
		List<Permission> permissions = new ArrayList<Permission>();
		String[] strArray = permissionForm.getStrArray();
		for (int i = 0; i < strArray.length; i++) {
			Permission permission = new Permission();
			PerssionId perssionId = new PerssionId();
			perssionId.setRoleId(roleId);
			perssionId.setFunctionId(Long.parseLong(strArray[i]));
			permission.setId(perssionId);
			permissions.add(permission);
		}
		State state = new StateImpl();
		rightDelegate.saveFunctionsToRole(permissions, state);

		//发布更新菜单指令 TODO
		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_FUNCTION_BY_ROLE.getNativeValue() + "/" + roleId,
				SecurityFowardPage.FIND_FUNCTION_BY_ROLE);
	}

	/**
	 * Update function by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param functionForm
	 *            the function form
	 * @return the string
	 */
	@RequestMapping("/updateFunctionById")
	public String updateFunctionById(HttpServletRequest request, HttpServletResponse response, FunctionForm functionForm) {
		log.debug("Struts FunctionAction updateFunctionById");
		State state = new StateImpl();
		rightDelegate.updateFunction(functionForm.getFunction(), state);
		return PathResolver.getPath(request, response, SecurityFowardPage.FUNCTION_LIST_QUERY);
	}

	// ////////////////////////////Role Controller
	/**
	 * Query.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param curPageNO
	 *            the cur page no
	 * @param roleId
	 *            the role id
	 * @param functionForm
	 *            the function form
	 * @return the string
	 */
	@RequestMapping("/deletePermissionByRoleId")
	public String deletePermissionByRoleId(HttpServletRequest request, HttpServletResponse response, String curPageNO,
			Long roleId, FunctionForm functionForm) {
		log.info("Action deletePermissionByRoleId with roleId {}", roleId);
		List<Permission> permissions = new ArrayList<Permission>();
		String[] strArray = functionForm.getStrArray();
		for (int i = 0; i < strArray.length; i++) {
			Permission permission = new Permission();
			PerssionId perssionId = new PerssionId();
			perssionId.setRoleId(roleId);
			perssionId.setFunctionId(Long.parseLong(strArray[i]));
			permission.setId(perssionId);
			permissions.add(permission);
		}
		State state = new StateImpl();
		rightDelegate.deleteFunctionsFromRole(permissions, state);
		request.setAttribute("roleId", roleId);
		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_FUNCTION_BY_ROLE.getNativeValue() + "/" + roleId,
				SecurityFowardPage.FIND_FUNCTION_BY_ROLE);
	}

	/**
	 * Find role by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param id
	 *            the id
	 * @return the string
	 */
	@RequestMapping("/findRoleById")
	public String findRoleById(HttpServletRequest request, HttpServletResponse response, Long id) {
		log.info("Action findRoleById with id  " + id);
		State state = new StateImpl();
		Role role = rightDelegate.findRoleById(id, state);
		request.setAttribute("role", role);

		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_ALL_ROLE);
	}

	/**
	 * Delete role by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param id
	 *            the id
	 * @return the string
	 */
	@RequestMapping("/deleteRoleById")
	public String deleteRoleById(HttpServletRequest request, HttpServletResponse response, Long id) {
		log.info("Struts Action deleteRoleById with id  " + id);
		State state = new StateImpl();

		rightDelegate.deleteRoleById(id, state);

		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_ALL_ROLE);
	}

	/**
	 * Find all role.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @return the string
	 */
	@RequestMapping("/findAllRole")
	public String findAllRole(HttpServletRequest request, HttpServletResponse response) {
		String userName = UserManager.getUserName(request);
		if (userName == null) {
			throw new BusinessException("not login yet", ErrorCodes.BUSINESS_ERROR);
		}
		// 权限检查
		String curPageNO = request.getParameter("curPageNO");
		String myaction;
		String search = request.getParameter("search");
		String action = "findAllRole";
		if (search == null) {
			search = "";
			myaction = action;
		} else {
			myaction = action + "?search=" + search;
		}

		State state = new StateImpl();
		PageSupport<Role> ps = rightDelegate.findAllRole(search,myaction, curPageNO, state);
		PageSupportHelper.savePage(request, ps);
		
		request.setAttribute("search", search);
		return PathResolver.getPath(request, response, SecurityBackPage.ROLE_LIST);
	}

	/**
	 * Find role by function.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param functionId
	 *            the function id
	 * @return the string
	 */
	@RequestMapping("/findRoleByFunction")
	public String findRoleByFunction(HttpServletRequest request, HttpServletResponse response, Long functionId) {
		log.info("Struts Action findRoleByFunction with function id  " + functionId);
		State state = new StateImpl();

		Function function = rightDelegate.findFunctionById(functionId, state);
		List list = rightDelegate.findRoleByFunction(functionId, state);

		request.setAttribute("list", list);
		request.setAttribute("function", function);

		return PathResolver.getPath(request, response, SecurityBackPage.FIND_ROLE_BY_FUNCTION);
	}

	/**
	 * Save role.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param roleForm
	 *            the role form
	 * @return the string
	 */
	@RequestMapping("/saveRole")
	public String saveRole(HttpServletRequest request, HttpServletResponse response, RoleForm roleForm) {
		State state = new StateImpl();

		Long id = rightDelegate.saveRole(roleForm.getRole(), state);
		log.info("success saveRole,id = " + id);

		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_ALL_ROLE);
	}

	/**
	 * Update role by id.
	 * 
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 * @param roleForm
	 *            the role form
	 * @return the string
	 */
	@RequestMapping("/updateRoleById")
	public String updateRoleById(HttpServletRequest request, HttpServletResponse response, RoleForm roleForm) {
		log.info("Struts Action updateRoleById");
		State state = new StateImpl();
		rightDelegate.updateRole(roleForm.getRole(), state);

		return PathResolver.getPath(request, response, SecurityFowardPage.FIND_ALL_ROLE);
	}

	@RequestMapping(value = "/delete/{id}")
	public String delete(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id) {
		log.info("Struts Action deleteFunctionById with id  " + id);
		State state = new StateImpl();
		boolean result = rightDelegate.deleteFunctionById(id, state);
		log.debug("deleteFunctionById result  = " + result);
		return PathResolver.getPath(request, response, SecurityFowardPage.FUNCTION_LIST_QUERY);
	}

	@RequestMapping("/load")
	public String load(HttpServletRequest request, HttpServletResponse response) {
		return PathResolver.getPath(request, response, SecurityBackPage.UPDATE_FUNCTION);
	}

	@RequestMapping("/query")
	public String query(HttpServletRequest request, HttpServletResponse response, String curPageNO, Function function) {
		request.setAttribute("bean", function);
		List<Menu> menuList = menuService.getManagedMenu();
		List<MenuTree> nodeList = new ArrayList<MenuTree>(menuList.size());
		
		request.setAttribute("curPageNO", curPageNO);
		request.setAttribute("function", function);		
		for( Menu me : menuList ){
			nodeList.add(new MenuTree( me.getMenuId(), me.getParentId(), me.getName(),false));
		}
		
		request.setAttribute("menuId",function.getMenuId());
			
		request.setAttribute("menuList", JSONUtil.getJson(nodeList));

		return PathResolver.getPath(request, response, SecurityTilesPage.FUNCTION_LIST);
	}
	
	/**
	 * 查询权限内容
	 * @param request
	 * @param response
	 * @param curPageNO
	 * @param function
	 * @return
	 */
	@RequestMapping("/querycontent")
	public String queryright(HttpServletRequest request, HttpServletResponse response, String curPageNO, Function function) {
		String userName = UserManager.getUserName(request);
		if (userName == null) {
			throw new BusinessException("not login yet", ErrorCodes.BUSINESS_ERROR);
		}
		State state = new StateImpl();
		PageSupport<Function> ps = rightDelegate.findAllFunction(curPageNO, function, state);
		PageSupportHelper.savePage(request, ps);
		request.setAttribute("bean", function);

		return PathResolver.getPath(request, response, SecurityBackPage.FUNCTION_LIST_CONTENT);
	}

	@RequestMapping(value = "/save")
	public String save(HttpServletRequest request, HttpServletResponse response, Function function) {
		State state = new StateImpl();
		Long id = function.getId();
		if (id == null) {
			id = rightDelegate.saveFunction(function, state);
		} else {
			rightDelegate.updateFunction(function, state);
		}
		log.info("success saveFunction,id = " + id);
		//发布更新菜单指令 TODO
		return PathResolver.getPath(request, response, SecurityFowardPage.FUNCTION_LIST_QUERY);
	}

	@RequestMapping(value = "/update/{id}")
	public String update(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id) {
		log.info("Struts Action findFunctionById with id  " + id);
		State state = new StateImpl();
		Function function = rightDelegate.findFunctionById(id, state);
		request.setAttribute("bean", function);
		if(function.getMenuId() != null){
			Menu menu  =menuService.getMenu(function.getMenuId());
			request.setAttribute("menu", menu);
		}

		return PathResolver.getPath(request, response, SecurityBackPage.UPDATE_FUNCTION);
	}

	@RequestMapping(value = "/roles/{id}")
	public String roles(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id) {
		log.info("Load Action findRoleByFunction with function id  " + id);
		State state = new StateImpl();

		Function function = rightDelegate.findFunctionById(id, state);
		List list = rightDelegate.findRoleByFunction(id, state);

		request.setAttribute("list", list);
		request.setAttribute("bean", function);

		return PathResolver.getPath(request, response, SecurityTilesPage.FIND_ROLE_BY_FUNCTION);
	}
	
	
	/**
	 * 加载菜单树
	 * @param request
	 * @param response
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/loadFunctionMenu")
	public String loadFunctionMenu(HttpServletRequest request, HttpServletResponse response, String menuId) {
		
		List<Menu> menuList = menuService.getManagedMenu();
		
		request.setAttribute("menuList", JSONUtil.getJson(constructMenuTree(menuList, menuId)));
		
		String path = PathResolver.getPath(request, response, SecurityBackPage.MENU_LOADFUNCMENU_PAGE);
		return path;
	}
	
	/**
	 * 用Ajax返回结果
	 * @param request
	 * @param response
	 * @param menuId
	 * @return
	 */
	@RequestMapping(value = "/loadAjaxFunctionMenu")
	public @ResponseBody List<MenuTree> loadAjaxFunctionMenu(HttpServletRequest request, HttpServletResponse response, String menuId) {
		List<Menu> menuList = menuService.getManagedMenu();
		return constructMenuTree(menuList, menuId);
	}
	
	/**
	 * 查询该权限拥有的用户
	 */
	@RequestMapping(value = "/loadUserByFunc")
	public String loadUserByFunc(HttpServletRequest request, HttpServletResponse response, String curPageNO,String userName,Long funcId){
		if (AppUtils.isBlank(funcId)) {
			return null;
		}
		
		Function function = functionService.getFunctionsById(funcId);
		if(function == null){
			return null;
		}else{
			request.setAttribute("func", function);
		}
		/////  分页查询 ////////
   		PageSupport ps = functionService.loadUserByFunction(curPageNO,userName,funcId );
   		PageSupportHelper.savePage(request, ps);
   		request.setAttribute("funcId", funcId);
   		request.setAttribute("userName", userName);
		return PathResolver.getPath(request, response, SecurityTilesPage.FUNCTION_USER_LIST_PAGE);
	}
	
	
	/**
	 * 组建树结构
	 * @param menuList 菜单列表
	 * @param menuId  当前菜单ID
	 * @return
	 */
	private List<MenuTree> constructMenuTree(List<Menu> menuList, String menuId ){
		List<MenuTree> treeList = new ArrayList<MenuTree>(menuList.size());
		
		//组建树结构
		for( Menu me : menuList ){
			treeList.add(new MenuTree( me.getMenuId(), me.getParentId(), me.getName()));
		}

		for( MenuTree tree : treeList ) {
			if( tree.getId().equals(menuId) ){
				tree.setChecked(true); //选中当前的菜单
				break;
			}
		}
		return treeList;
	}
	
}
